﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.UI;
using YArchitech.Controls;
using YArchitech.HVAC;
using YArchitech.LIB;
using YArchitech.Revit;
using YArchitech.Revit.RevitExtension;

namespace YArchitech.Plumbing
{
	[Transaction(TransactionMode.Manual)]
	[Regeneration(RegenerationOption.Manual)]
	public class HeatingPipeCreate : IExternalCommand
	{
		[DllImport("user32.dll", EntryPoint = "SendMessageA")]
		public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);

		public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
		{
			Transaction transaction = null;
			UIApplication application = commandData.Application;
			Autodesk.Revit.ApplicationServices.Application application2 = application.Application;
			Document document = application.ActiveUIDocument.Document;
			UIDocument activeUIDocument = commandData.Application.ActiveUIDocument;
			List<string> levelUp = new List<string>();
			levelUp = YJKElementFilter.GetElementNameByClass(typeof(Level), document);
			double offset = 0.0;
			HYPipeConnect myPipeConnect = new HYPipeConnect();
			List<ViewType> list = YJKRevitTools.ListViewNeed(1);
            list.Add((ViewType)3);
			if (!YJKRevitTools.ViewCheck(activeUIDocument, list))
			{
				return Autodesk.Revit.UI.Result.Cancelled;
			}
			if (HeatingPipeCreate.hWndRevit == null)
			{
				HeatingPipeCreate.hWndRevit = new YJKWindowHandle(Process.GetCurrentProcess().MainWindowHandle);
			}
			FormCreateHeatingPipe formCreateHeatingPipe = new FormCreateHeatingPipe(document, levelUp);
			if ((int)document.ActiveView.ViewType == 3)
			{
				formCreateHeatingPipe.textBoxLevel.Enabled = false;
				formCreateHeatingPipe.hyTextBox1.Enabled = false;
				formCreateHeatingPipe.textBoxOffset.Enabled = false;
			}
			formCreateHeatingPipe.Show(HeatingPipeCreate.hWndRevit);
			int wMsg = 7;
			HeatingPipeCreate.SendMessage(HeatingPipeCreate.hWndRevit.Handle, wMsg, IntPtr.Zero, IntPtr.Zero);
			Result result;
			for (;;)
			{
				try
				{
					Plane plane = null;
					if ((int)document.ActiveView.ViewType == 3)
					{
						plane = this.thwartwiseCreate.CreateWorkPlane(document);
					}
					HYHeatingPipeSystemType.IsOpenTran = false;
					XYZ xyz = activeUIDocument.Selection.PickPoint("请选择绘制暖管所基于线的起点（坡度将以该点为起点）...");
					XYZ xyz2 = null;
					if (xyz != null)
					{
						HYHeatingPipeSystemType.IsOpenTran = true;
						Pipe pipe = null;
						Pipe pipe2 = null;
						for (;;)
						{
							transaction = new Transaction(document, "绘制暖管");
							transaction.Start();
							try
							{
								if ((int)document.ActiveView.ViewType != 3)
								{
									offset = double.Parse(formCreateHeatingPipe.textBoxOffset.Text);
								}
								if (formCreateHeatingPipe.Visible)
								{
									using (PipeCreateJigPolarAxis pipeCreateJigPolarAxis = new PipeCreateJigPolarAxis(activeUIDocument, offset, formCreateHeatingPipe))
									{
										pipeCreateJigPolarAxis.StartPoint = xyz;
										pipeCreateJigPolarAxis.DrawSize = true;
                                        System.Windows.Forms.Application.DoEvents();
										pipeCreateJigPolarAxis.SetPromptState("", false, true);
										xyz2 = pipeCreateJigPolarAxis.PickEndPoint(xyz, "请选择绘制暖管所基于线的终点...");
										pipeCreateJigPolarAxis.Dispose();
									}
									if (xyz2 == null)
									{
										break;
									}
									if (xyz2.IsAlmostEqualTo(xyz))
									{
										MessageBox.Show("选择的两点过于接近，无法创建！", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
										break;
									}
									if (formCreateHeatingPipe.systemType.currentSystemTypeInfo == null || formCreateHeatingPipe.systemType.currentSystemTypeInfo.SysType == null || formCreateHeatingPipe.systemType.currentSystemTypeInfo.PipeType == null)
									{
										YJKMessageBox.Show("需要选择系统类型");
										break;
									}
									if ((int)document.ActiveView.ViewType == 3)
									{
										PipeType pipeType = formCreateHeatingPipe.Get_PipeType(document, formCreateHeatingPipe.systemType.currentSystemTypeInfo.PipeType);
										PipingSystemType pipingSystemType = formCreateHeatingPipe.Get_PipingSystemType(document, formCreateHeatingPipe.systemType.currentSystemTypeInfo.SysType);
										string text = formCreateHeatingPipe.comboBoxPipeDiameter.Text;
										List<Pipe> elevationIntersectPipes = this.thwartwiseCreate.GetElevationIntersectPipes(xyz, plane.Normal, document);
										if (elevationIntersectPipes.Count<Pipe>() > 0)
										{
											Pipe connPipe = this.thwartwiseCreate.GetConnPipe(elevationIntersectPipes, xyz);
											XYZ project = new YJKPiping<Pipe>(connPipe).GetProject(xyz);
											XYZ xyz3 = project.Subtract(xyz);
											XYZ xyz4 = xyz2.Add(xyz3);
											if (YJKRevitTools.getNewXYZDeriction(project, xyz4) != null)
											{
												pipe2 = document.CreatHYPipe(pipingSystemType, pipeType, formCreateHeatingPipe.Get_Level(document), project, xyz4, double.Parse(text));
											}
											List<Pipe> list2 = new List<Pipe>();
											pipe = pipe2;
											list2.Add(connPipe);
											list2.Add(pipe);
											SubTransaction subTransaction = new SubTransaction(document);
											subTransaction.Start();
											try
											{
												this.thwartwiseCreate.ConnectPipes(list2, ref pipe, myPipeConnect);
												subTransaction.Commit();
												goto IL_3B6;
											}
											catch (Exception)
											{
												subTransaction.RollBack();
												goto IL_3B6;
											}
										}
										if (YJKRevitTools.getNewXYZDeriction(xyz, xyz2) != null)
										{
											pipe2 = document.CreatHYPipe(pipingSystemType, pipeType, formCreateHeatingPipe.Get_Level(document), xyz, xyz2, double.Parse(text));
										}
										pipe = pipe2;
										IL_3B6:
										XYZ point = xyz;
										xyz = xyz2;
										xyz2 = null;
										List<Element> elementByCollision = this.thwartwiseCreate.GetElementByCollision(pipe, BuiltInCategory.OST_PipeCurves, document);
										this.thwartwiseCreate.CrossElevationConnPipes(elementByCollision, pipe, point, plane.Normal, myPipeConnect);
									}
									else
									{
										double num = double.Parse(formCreateHeatingPipe.textBoxLevel.Text) * 1000.0 + formCreateHeatingPipe.Get_Level(document).ProjectElevation * 304.8;
										offset = double.Parse(formCreateHeatingPipe.textBoxOffset.Text);
										PipeType pipeType = formCreateHeatingPipe.Get_PipeType(document, formCreateHeatingPipe.systemType.currentSystemTypeInfo.PipeType);
										PipingSystemType pipingSystemType = formCreateHeatingPipe.Get_PipingSystemType(document, formCreateHeatingPipe.systemType.currentSystemTypeInfo.SysType);
										string text = formCreateHeatingPipe.comboBoxPipeDiameter.Text;
										double slope;
										if (formCreateHeatingPipe.hyTextBox1.Visible)
										{
											slope = double.Parse(formCreateHeatingPipe.hyTextBox1.Text);
										}
										else
										{
											slope = 0.0;
										}
										XYZ newXYZDeriction = YJKRevitTools.getNewXYZDeriction(xyz, xyz2);
										HYCreatePipeHelper hycreatePipeHelper = new HYCreatePipeHelper();
										if (newXYZDeriction != null)
										{
											if (pipe != null && pipe.IsValidObject)
											{
												double createPipeLevel = this.thwartwiseCreate.GetCreatePipeLevel(document, ref pipe, xyz, xyz2, num, slope, offset, newXYZDeriction, hycreatePipeHelper);
												pipe2 = hycreatePipeHelper.DrawThwartwisePipe(document, offset, createPipeLevel, xyz, xyz2, pipeType, double.Parse(text), pipingSystemType, slope, newXYZDeriction);
											}
											else
											{
												pipe2 = hycreatePipeHelper.DrawThwartwisePipe(document, offset, num, xyz, xyz2, pipeType, double.Parse(text), pipingSystemType, slope, newXYZDeriction);
											}
										}
										Line curve = (pipe2.Location as LocationCurve).Curve as Line;
										formCreateHeatingPipe.textBoxLevel.Text = Math.Round((curve.GetEndPoint(1).Z - formCreateHeatingPipe.Get_Level(document).ProjectElevation) * 0.3048, 3).ToString();
										Line pipeline = YJKLineEx.YJKGetBound(xyz, xyz2);
										XYZ newParallelPipeXYZ = hycreatePipeHelper.getNewParallelPipeXYZ(xyz, pipeline, offset, newXYZDeriction);
										XYZ start = xyz;
										xyz = xyz2;
										xyz2 = null;
										if (pipe != null && pipe.IsValidObject && pipe2 != null)
										{
											Curve curve2 = (pipe.Location as LocationCurve).Curve;
											Curve curve3 = (pipe2.Location as LocationCurve).Curve;
											YJKLine hyline = new YJKLine(curve2.GetEndPoint(0), curve2.GetEndPoint(1));
											YJKLine hyline2 = new YJKLine(curve3.GetEndPoint(0), curve3.GetEndPoint(1));
											if (!hyline.IsLineOnLine(hyline2.Line) && !hyline.IsXYParallel(hyline2.Line))
											{
												List<Pipe> list3 = new List<Pipe>();
												list3.Add(pipe);
												list3.Add(pipe2);
												list3 = this.thwartwiseCreate.ExtendPipe(list3, start);
												if (list3 != null)
												{
													XYZ xyz5 = hyline.IntersectionPoint(hyline2.Line);
													int num2 = 1;
													int num3 = 1;
													if (xyz5 != null)
													{
														num2 = (hyline.EndPoint.IsAlmostEqualTo(xyz5, 0.001) ? 1 : -1);
														num3 = (hyline2.StartPoint.IsAlmostEqualTo(xyz5, 0.001) ? 1 : -1);
													}
													XYZ xyz6 = (hyline.EndPoint - hyline.StartPoint).Normalize() * (double)num2;
													XYZ xyz7 = (hyline2.EndPoint - hyline2.StartPoint).Normalize() * (double)num3;
													YJKPipeConnectorHelper hypipeConnectorHelper = new YJKPipeConnectorHelper();
													if ((Math.Abs(xyz6.X) < 1E-06 && Math.Abs(xyz7.Y) < 1E-06) || (Math.Abs(xyz6.Y) < 1E-06 && Math.Abs(xyz7.X) < 1E-06))
													{
														if (!this.thwartwiseCreate.NewElbowFitting(list3, true))
														{
															MessageBox.Show("没有可以使用的族配置，请检查Revit的族配置", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
															transaction.RollBack();
															break;
														}
													}
													else if (xyz6.AngleTo(xyz7) * 180.0 / Math.PI <= 90.0)
													{
														if (!this.thwartwiseCreate.NewElbowFitting(list3, true))
														{
															MessageBox.Show("没有可以使用的族配置，请检查Revit的族配置", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
															transaction.RollBack();
															break;
														}
													}
													else
													{
														hypipeConnectorHelper.connect45Elbow(pipe, this.thwartwiseCreate.getxyz(pipe), pipe2, this.thwartwiseCreate.getxyz(pipe2), document);
													}
												}
											}
										}
										pipe = pipe2;
										List<Pipe> pickPipe = this.thwartwiseCreate.GetPickPipe(newParallelPipeXYZ, 0.032808398950131233, document);
										SubTransaction subTransaction2 = new SubTransaction(document);
										subTransaction2.Start();
										try
										{
											this.thwartwiseCreate.ConnectPipes(pickPipe, ref pipe, myPipeConnect, newParallelPipeXYZ);
											subTransaction2.Commit();
										}
										catch (Exception)
										{
											subTransaction2.RollBack();
										}
										List<Element> elementByCollision2 = this.thwartwiseCreate.GetElementByCollision(pipe, BuiltInCategory.OST_PipeCurves, document);
										this.thwartwiseCreate.CrossConnPipes(elementByCollision2, ref pipe, newParallelPipeXYZ, myPipeConnect);
									}
								}
							}
							catch (Autodesk.Revit.Exceptions.OperationCanceledException)
							{
								pipe = null;
								transaction.RollBack();
								break;
							}
							document.Regenerate();
							transaction.Commit();
						}
						continue;
					}
					formCreateHeatingPipe.Close();
					result = Autodesk.Revit.UI.Result.Succeeded;
				}
				catch (Autodesk.Revit.Exceptions.OperationCanceledException)
				{
					formCreateHeatingPipe.Close();
					result = Autodesk.Revit.UI.Result.Succeeded;
				}
				catch (Exception ex)
				{
					if (ex.Message.Contains("Fitting cannot be created between the input connectors because the angle between them is too small or too large."))
					{
						MessageBox.Show("您绘制管道与上一次绘制管道夹角过大或过小！", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
					}
					else if (ex.Message.Contains("failed to insert elbow."))
					{
						MessageBox.Show("没有可以使用的族配置，请检查Revit的族配置", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
					}
					else
					{
						MessageBox.Show(ex.Message, "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
					}
					this.thwartwiseCreate.EndTransation(transaction, false);
					formCreateHeatingPipe.Close();
					result = Autodesk.Revit.UI.Result.Succeeded;
				}
				finally
				{
					this.thwartwiseCreate.EndTransation(transaction, true);
				}
				break;
			}
			return result;
		}

		public static YJKWindowHandle hWndRevit;

		private ThwartwiseCreate thwartwiseCreate = new ThwartwiseCreate();
	}
}
